package com.ys.nms.module.business.controller.admin.redData;


import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.Session;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
@AllArgsConstructor
public class RrdToolReaderForWindows {

    private final SshConfig sshConfig;

    // Linux服务器上的RRD文件路径
    private final String remoteRrdBasePath = "/home/fengli/librenms-master/examples/compose/librenms/rrd";

    /**
     * 查询RRD数据（通过SSH在远程Linux服务器上执行）
     */
    public RrdQueryResult queryRrdData(RrdQueryParams params) {
        Session session = null;
        ChannelExec channel = null;

        try {
            if (!validateParams(params)) {
                return new RrdQueryResult("参数验证失败", params);
            }

            // 构建远程RRD文件路径
            String rrdFilePath = buildRrdFilePath(params.getDeviceIp(), params.getRrdFile());

            // 构建远程命令
            String command = String.format("rrdtool fetch %s AVERAGE --start %s --end %s",
                    rrdFilePath, params.getStartTime(), params.getEndTime());

            log.info("执行远程RRDtool命令: {}", command);

            // 创建SSH会话
            session = sshConfig.createSession();
            session.connect();

            // 执行命令
            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            channel.setInputStream(null);

            InputStream in = channel.getInputStream();
            channel.connect();

            // 读取命令输出
            List<String> outputLines = readRemoteOutput(in);

            // 检查命令执行状态
            int exitStatus = channel.getExitStatus();
            if (exitStatus != 0) {
                throw new Exception("远程RRDtool命令执行失败，退出码: " + exitStatus);
            }

            List<RrdDataPoint> dataPoints = parseRrdOutput(outputLines);
            return new RrdQueryResult(dataPoints, params);

        } catch (Exception e) {
            log.error("通过SSH查询RRD数据时发生错误: {}", e.getMessage(), e);
            return new RrdQueryResult("SSH查询失败: " + e.getMessage(), params);
        } finally {
            // 清理资源
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
    }

    /**
     * 查询RRD数据（简化参数版本）
     */
    public RrdQueryResult queryRrdData(String deviceIp, String rrdFile, String startTime, String endTime) {
        RrdQueryParams params = new RrdQueryParams();
        params.setDeviceIp(deviceIp);
        params.setRrdFile(rrdFile);
        params.setStartTime(startTime);
        params.setEndTime(endTime);
        return queryRrdData(params);
    }

    /**
     * 获取设备可用的RRD文件列表（通过SSH在远程执行）
     */
    public List<String> getAvailableRrdFiles(String deviceIp) {
        Session session = null;
        ChannelExec channel = null;

        try {
            String devicePath = String.format("%s/%s", remoteRrdBasePath, deviceIp);
            String command = String.format("find %s -name \"*.rrd\" -printf \"%%f\\n\"", devicePath);

            session = sshConfig.createSession();
            session.connect();

            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            channel.setInputStream(null);

            InputStream in = channel.getInputStream();
            channel.connect();

            List<String> files = readRemoteOutput(in);

            int exitStatus = channel.getExitStatus();
            if (exitStatus != 0) {
                log.warn("查找RRD文件命令执行失败，退出码: {}", exitStatus);
                return List.of();
            }

            return files.stream()
                    .sorted()
                    .collect(Collectors.toList());

        } catch (Exception e) {
            log.error("获取RRD文件列表失败: {}", e.getMessage());
            return List.of();
        } finally {
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
    }

    /**
     * 检查设备是否可用（通过SSH在远程执行）
     */
    public boolean isDeviceAvailable(String deviceIp) {
        Session session = null;
        ChannelExec channel = null;

        try {
            String devicePath = String.format("%s/%s", remoteRrdBasePath, deviceIp);
            String command = String.format("test -d %s && echo \"EXISTS\" || echo \"NOT_EXISTS\"", devicePath);

            session = sshConfig.createSession();
            session.connect();

            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            channel.setInputStream(null);

            InputStream in = channel.getInputStream();
            channel.connect();

            List<String> result = readRemoteOutput(in);

            return result.size() > 0 && "EXISTS".equals(result.get(0));

        } catch (Exception e) {
            log.error("检查设备目录失败: {}", e.getMessage());
            return false;
        } finally {
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
    }

    /**
     * 测试SSH连接
     */
    public boolean testSshConnection() {
        return sshConfig.testConnection();
    }

    /**
     * 获取远程服务器信息
     */
    public String getRemoteServerInfo() {
        Session session = null;
        ChannelExec channel = null;

        try {
            String command = "uname -a && echo '---' && df -h | grep rrd";

            session = sshConfig.createSession();
            session.connect();

            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            channel.setInputStream(null);

            InputStream in = channel.getInputStream();
            channel.connect();

            List<String> output = readRemoteOutput(in);
            return String.join("\n", output);

        } catch (Exception e) {
            return "获取服务器信息失败: " + e.getMessage();
        } finally {
            if (channel != null && channel.isConnected()) {
                channel.disconnect();
            }
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
    }

    /**
     * 读取远程命令输出
     */
    private List<String> readRemoteOutput(InputStream in) throws Exception {
        List<String> lines = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String trimmedLine = line.trim();
                if (!trimmedLine.isEmpty()) {
                    lines.add(trimmedLine);
                }
            }
        }
        return lines;
    }

    /**
     * 构建远程RRD文件路径
     */
    private String buildRrdFilePath(String deviceIp, String rrdFile) {
        return String.format("%s/%s/%s", remoteRrdBasePath, deviceIp, rrdFile);
    }

    /**
     * 参数验证
     */
    private boolean validateParams(RrdQueryParams params) {
        if (params.getDeviceIp() == null || params.getDeviceIp().trim().isEmpty()) {
            log.error("设备IP不能为空");
            return false;
        }
        if (params.getRrdFile() == null || params.getRrdFile().trim().isEmpty()) {
            log.error("RRD文件名不能为空");
            return false;
        }
        return true;
    }

    /**
     * 解析RRD输出（与原始版本相同）
     */
    private List<RrdDataPoint> parseRrdOutput(List<String> outputLines) {
        return outputLines.stream()
                .filter(line -> !line.startsWith(" ") && !line.contains("timestamp") && !line.isEmpty())
                .map(this::parseDataLine)
                .filter(point -> point != null)
                .collect(Collectors.toList());
    }

    /**
     * 解析数据行（与原始版本相同）
     */
    private RrdDataPoint parseDataLine(String line) {
        try {
            String[] parts = line.split(":");
            if (parts.length != 2) {
                log.warn("数据行格式错误: {}", line);
                return null;
            }

            Long timestamp = Long.parseLong(parts[0].trim());
            String valueStr = parts[1].trim();

            Double value = "-nan".equalsIgnoreCase(valueStr) || "nan".equalsIgnoreCase(valueStr) ?
                    Double.NaN : Double.parseDouble(valueStr);

            RrdDataPoint point = new RrdDataPoint();
            point.setTimestamp(timestamp);
            point.setValue(value);
            return point;

        } catch (NumberFormatException e) {
            log.warn("解析数据行失败: {}", line);
            return null;
        }
    }

    /**
     * 获取有效数据点（与原始版本相同）
     */
    public List<RrdDataPoint> getValidDataPoints(RrdQueryResult result) {
        return result.getDataPoints().stream()
                .filter(RrdDataPoint::isValid)
                .collect(Collectors.toList());
    }
}